﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;
using System.Collections;

namespace IService.DataDLL
{
    /// <summary>
    /// 数据库操作方法的基类
    /// </summary>
    public class BaseMethod
    {
        private Type infoType;
        private PropertyInfo[] _propertyInfos;
        private BaseInfo entity;
        private TableAttribute _currentTableAttribute;
        private string _tableName;
        private long _identity;
        public BaseMethod(Type infoType)
        {
            this.entity = null;
            this._propertyInfos = null;
            this._currentTableAttribute = null;
            this._tableName = null;
            this.infoType = infoType;
            this._identity = -2147483648L;
        }

        public BaseMethod(BaseInfo info)
            : this(info.GetType())
        {
            this.entity = info;
        }

        public BaseMethod(string TableName, BaseInfo info)
            : this(info)
        {
            this._tableName = TableName;
        }

        public Type InfoType
        {
            get
            {
                return this.infoType;
            }
        }

        public BaseInfo Entity
        {
            get
            {
                return this.entity;
            }
        }

        /// <summary>
        /// 数据库表名
        /// </summary>
        protected string TableName
        {
            get
            {
                if (this._tableName == null)
                {
                    this._tableName = this.CurrentTableAttribute.TableName;
                }
                return this._tableName;
            }
        }

        /// <summary>
        /// 获取当前表信息
        /// </summary>
        protected TableAttribute CurrentTableAttribute
        {
            get
            {
                if (this._currentTableAttribute == null)
                {
                    if (this.InfoType == null)
                    {
                        return null;
                    }
                    object[] tattrs = this.InfoType.GetCustomAttributes(typeof(TableAttribute), true);
                    if (tattrs.Length <= 0)
                    {
                        return null;
                    }
                    this._currentTableAttribute = tattrs[0] as TableAttribute;
                }
                return this._currentTableAttribute;
            }
        }

        /// <summary>
        /// 自增列SQL条件
        /// </summary>
        protected string IdentityWhereClause
        {
            get
            {
                return string.Concat(new object[] { "[", this.CurrentTableAttribute.IdentityColumn, "]=", this.Identity });
            }
        }

        /// <summary>
        /// 自增列的值
        /// </summary>
        protected long Identity
        {
            get
            {
                if (this._identity < 0L)
                {
                    return Convert.ToInt64(this.InfoType.GetProperty(this.CurrentTableAttribute.IdentityColumn).GetValue(this.Entity, null));
                }
                return this._identity;
            }
            set
            {
                this._identity = value;
            }
        }

        /// <summary>
        /// 是否存在自增列
        /// </summary>
        protected bool HasIdentity
        {
            get
            {
                return !string.IsNullOrEmpty(this.CurrentTableAttribute.IdentityColumn);
            }
        }

        /// <summary>
        /// 向StrinBuilder中写入Sql插入语句
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="format"></param>
        /// <param name="concat"></param>
        /// <param name="PIs"></param>
        /// <param name="ShouldIdentity">是否将自增列作为参数</param>
        protected void AppendParameterString(StringBuilder sb, string format, string concat, bool ShouldIdentity)
        {
            string tmpConcat = string.Empty;
            PropertyInfo[] PIs = this.PropertyInfos;
            foreach (PropertyInfo pi in PIs)
            {
                PropertyAttribute attr = GetPropertyAttribute(pi);
                if (IsParameter(attr))
                {
                    if (!attr.IsIdentity || (attr.IsIdentity && ShouldIdentity))
                    {
                        sb.Append(tmpConcat);
                        sb.AppendFormat(format, attr.ColumnName);
                        tmpConcat = concat;
                    }
                }
            }
        }

        /// <summary>
        /// 判断属性是否可用
        /// </summary>
        /// <param name="attr"></param>
        /// <returns></returns>
        protected static bool IsParameter(PropertyAttribute attr)
        {
            return (attr != null);
        }

        /// <summary>
        /// 判断该字段是不是非自增
        /// </summary>
        /// <param name="attr"></param>
        /// <returns></returns>
        protected static bool IsNotIdentity(PropertyAttribute attr)
        {
            return (IsParameter(attr) && !attr.IsIdentity);
        }

        /// <summary>
        /// 获取SQL参数
        /// </summary>
        /// <param name="SelectIdentity">是否需要将自增列作为参数</param>
        /// <returns></returns>
        protected IDataParameter[] GetParameters(bool ShouldIdentity)
        {
            ArrayList paraList = new ArrayList();
            foreach (PropertyInfo pi in this.PropertyInfos)
            {
                PropertyAttribute attr = GetPropertyAttribute(pi);
                if (IsParameter(attr))
                {
                    if (!attr.IsIdentity || (attr.IsIdentity && ShouldIdentity))
                    {
                        IDataParameter para = DBHelperFactory.CreateParameter(DBHelperFactory.DB_CURRENT, attr);
                        if (para != null)
                        {
                            para.Value = pi.GetValue(this.Entity, null);
                            paraList.Add(para);
                        }
                    }
                }
            }
            return (paraList.ToArray(typeof(IDataParameter)) as IDataParameter[]);
        }

        /// <summary>
        /// 获取所有的属性
        /// </summary>
        protected PropertyInfo[] PropertyInfos
        {
            get
            {
                if (this._propertyInfos == null)
                {
                    this._propertyInfos = this.InfoType.GetProperties();
                }
                return this._propertyInfos;
            }
        }

        /// <summary>
        /// 获取属性信息
        /// </summary>
        /// <param name="pi"></param>
        /// <returns></returns>
        protected static PropertyAttribute GetPropertyAttribute(PropertyInfo pi)
        {
            return (Attribute.GetCustomAttribute(pi, typeof(PropertyAttribute), false) as PropertyAttribute);
        }

        #region 数据交互

        /// <summary>
        /// 判断DataSet是否有表
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        protected static bool HasData(DataSet ds)
        {
            return (ds.Tables.Count > 0);
        }
        /// <summary>
        /// 执行command，返回是否成功
        /// </summary>
        /// <param name="CommandText"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        protected bool ExecuteBool(string CommandText, IDataParameter[] paras)
        {
            IDBHelper helper = DBHelperFactory.CreateInstance(DBHelperFactory.DB_CURRENT);
            return helper.ExecuteBoolWithCommand(CommandText, paras);
        }
        /// <summary>
        /// 执行command，返回影响记录行数（NonQuery）
        /// </summary>
        /// <param name="type"></param>
        /// <param name="text"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        protected int ExecuteNonQuery(string CommandText, IDataParameter[] paras)
        {
            IDBHelper helper = DBHelperFactory.CreateInstance(DBHelperFactory.DB_CURRENT);
            return helper.ExecuteNonQueryWithCommand(CommandText, paras);
        }
        /// <summary>
        /// 执行command，返回DataSet
        /// </summary>
        /// <param name="type"></param>
        /// <param name="text"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        protected DataSet ExecuteDataset(string CommandText, IDataParameter[] paras)
        {
            IDBHelper helper = DBHelperFactory.CreateInstance(DBHelperFactory.DB_CURRENT);
            return helper.ExecuteDataSetWithCommand(CommandText, paras);
        }
        /// <summary>
        /// 执行command，返回DataTable
        /// </summary>
        /// <param name="CommandText"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        protected DataTable ExecuteDataTable(string CommandText, IDataParameter[] paras)
        {
            IDBHelper helper = DBHelperFactory.CreateInstance(DBHelperFactory.DB_CURRENT);
            return helper.ExecuteDataTableWithCommand(CommandText, paras);
        }
        /// <summary>
        /// 执行command，返回object
        /// </summary>
        /// <param name="CommandText"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        protected object ExecuteScalar(string CommandText, IDataParameter[] paras)
        {
            IDBHelper helper = DBHelperFactory.CreateInstance(DBHelperFactory.DB_CURRENT);
            return helper.ExecuteScalarWithCommand(CommandText, paras);
        }
        #endregion
        /// <summary>
        /// 将Datarow转化为HashTable
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        protected Hashtable GetHashTableByDatarow(DataRow row)
        {
            Hashtable table = new Hashtable();
            if (row == null)
            {
                return table;
            }
            PropertyInfo[] pis = this.PropertyInfos;
            foreach (PropertyInfo pi in pis)
            {
                table.Add(pi.Name, row[pi.Name]);
            }
            return table;
        }
    }
}
